package p03;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * 什么是模板方法模式？
 * 模板方法模式是一种行为设计模式，它定义了一个操作中的算法骨架，而将一些步骤延迟到子类中实现。
 * 该模式使得子类可以不改变算法结构的情况下重新定义算法的某些特定步骤。
 * <p>
 * bean后处理器，可以认为是一种模板方法模式的经典实现
 * 将不变的代码写死(生命周期各个节点是固定的),变化的代码抽象出来(在生命周期的各个节点回调哪些方法，是变化的)
 *
 * @author Chen weishuai
 * @since 2025/7/18
 */
@Slf4j
public class TemplateMethodPatternDemo {

    public static void main(String[] args) {
        /**
         * 给某个结点前后进行扩展，利用的是设计模式:模板方法模式
         *      将不变的写死，将变化的抽象成接口
         * 代码见TemplateMethod
         *      我们将自定义的扩展交给beanPostProcessors数组，TemplateMethod就会一一执行我们的自定义扩展
         */
        TemplateMethod templateMethod = new TemplateMethod();
        // 添加两个后处理器
        templateMethod.beanPostProcessors.add(bean -> log.info("初始化" + bean + "之前执行"));
        templateMethod.beanPostProcessors.add(bean -> log.info("初始化" + bean + "之后执行"));
        // getBean会回调我们添加的后处理器的init方法
        templateMethod.getBean();

    }

    static class TemplateMethod {

        private List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();

        public Object getBean() {
            /**
             * 这里模拟了构造一个bean给过程中，在不同的生命周期阶段调用不同的回调函数
             */
            TestBean testBean = new TestBean();
            log.info("构造" + testBean);
            log.info("依赖注入" + testBean);
            for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {

                beanPostProcessor.init(testBean);
            }
            log.info("销毁" + testBean);
            return testBean;
        }


    }

    /**
     * 模拟了一个后处理器接口
     */
    interface BeanPostProcessor {
        void init(Object bean);
    }
}
